package com.bsoft.gol.editor.fileUpload;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public abstract class AbstractExcelDataReaderSupport<T extends AbstractInExcel> implements ExcelDataReader<T>{

	private static final Logger logger = LoggerFactory.getLogger(AbstractExcelDataReaderSupport.class);
	
	protected Class<T> clazz;
	private List<Field> fields = new ArrayList<Field>();
	protected List<String> emptyIdentities;
	
	@Override
	public TableData<T> read(InputStream inputStream,String fileName) {
		long start = System.currentTimeMillis();
		logger.info("开始读入.....");
		TableData<T> tableData = null;
		Workbook wb = null;
		String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
		logger.info("要读入的文件:" + fileName);
		if("xlsx".equals(ext) || "xls".equals(ext)){
			try {
				long startLong = System.currentTimeMillis();
				wb = WorkbookFactory.create(inputStream);// new XSSFWorkbook(inputStream);
				long endLong = System.currentTimeMillis();
				logger.info("加载文件[" + fileName + "]耗时" + (endLong - startLong) + "ms");
			} catch (IOException | InvalidFormatException e) {
				e.printStackTrace();
			} 
			if(wb == null){
				logger.info("要读入的文件[excel]为空");
				return null;
			}
			int sheetCount = wb.getNumberOfSheets();
			for(int j = 0 ; j < sheetCount; ){//改成只读表0
				try {
					tableData = readSheet4Xlsx(wb.getSheetAt(j));
				} catch (InstantiationException | IllegalAccessException e) {
					e.printStackTrace();
				}
				break;
			}
		}
		long end = System.currentTimeMillis();
		logger.info(fileName + "读取完成，共" + tableData.getCount() + "条，耗时" + (end - start) + "ms");
		return tableData;
	}

	public TableData<T> readFromBeginRow(InputStream inputStream,String fileName,int beginRow) {
		long start = System.currentTimeMillis();
		logger.info("开始读入.....");
		TableData<T> tableData = null;
		Workbook wb = null;
		String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
		logger.info("要读入的文件:" + fileName);
		if("xlsx".equals(ext) || "xls".equals(ext)){
			try {
				long startLong = System.currentTimeMillis();
				wb = WorkbookFactory.create(inputStream);// new XSSFWorkbook(inputStream);
				long endLong = System.currentTimeMillis();
				logger.info("加载文件[" + fileName + "]耗时" + (endLong - startLong) + "ms");
			} catch (IOException | InvalidFormatException e) {
				e.printStackTrace();
			}
			if(wb == null){
				logger.info("要读入的文件[excel]为空");
				return null;
			}
			int sheetCount = wb.getNumberOfSheets();
			for(int j = 0 ; j < sheetCount; ){//改成只读表0
				try {
					tableData = readSheet4XlsxFromBeginRow(wb.getSheetAt(j), beginRow);
				} catch (InstantiationException | IllegalAccessException e) {
					e.printStackTrace();
				}
				break;
			}
		}
		long end = System.currentTimeMillis();
		logger.info(fileName + "读取完成，共" + tableData.getCount() + "条，耗时" + (end - start) + "ms");
		return tableData;
	}
	
	private TableData<T> readSheet4Xlsx(Sheet sheet) throws InstantiationException, IllegalAccessException{
		TableData<T> tableData = new TableData<T>();
    	int rowCount = sheet.getPhysicalNumberOfRows();
    	for(int j = 1; j < rowCount ; j ++) {
    		Row row = sheet.getRow(j);
    		if(row == null){
    			continue;
    		}
    		T t = clazz.newInstance();
    		RowParser.parseRow(t, row, fields,emptyIdentities);
    		if(t.isEmptyRow()){//中间有空行时，则终止往下读取
    			break;
    		}
    		t.setRowIndex(j);
    		tableData.addRowDataItem(t);
    	}
    	return tableData;
    }

	private TableData<T> readSheet4XlsxFromBeginRow(Sheet sheet, int beginRow) throws InstantiationException, IllegalAccessException{
		TableData<T> tableData = new TableData<T>();
		int rowCount = sheet.getPhysicalNumberOfRows();
		for(int j = beginRow; j < rowCount ; j ++) {
			Row row = sheet.getRow(j);
			if(row == null){
				continue;
			}
			T t = clazz.newInstance();
			RowParser.parseRow(t, row, fields,emptyIdentities);
			if(t.isEmptyRow()){//中间有空行时，则终止往下读取
				break;
			}
			t.setRowIndex(j);
			tableData.addRowDataItem(t);
		}
		return tableData;
	}

	@Override
	public abstract void setupClass() ;
	
	@Override
	public void initFields() {
		setupClass();
		Field[] fieldArr = clazz.getDeclaredFields();
		for(Field field : fieldArr){
			if(field.isAnnotationPresent(ColumnRelation.class)){
				ColumnRelation annotation = field.getAnnotation(ColumnRelation.class);
				if(!annotation.ignore()){
					fields.add(field);
				}
			}
		}
	}

}
